package com.team.easybuy.service.Impl;

import com.team.easybuy.entity.User;
import com.team.easybuy.mapper.UserMapper;
import com.team.easybuy.service.UserService;
import com.team.easybuy.util.CodeUtil;
import com.team.easybuy.util.EmailUtil;
import com.team.easybuy.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private JavaMailSender javaMailSender;


    @Override
    public User checkLogin(User user, HttpServletRequest req, HttpServletResponse resp) {
        User login = userMapper.checkLogin(user);
        if (login == null) {
            return null;
        }
        String uuid = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(uuid, login, 30, TimeUnit.MINUTES);
        Cookie cookie = new Cookie("uuid", uuid);
        cookie.setPath("/");
        resp.addCookie(cookie);
        return login;
    }

    @Override
    public boolean addUser(User user) {
        user.setType(0);
        int count = userMapper.insertUser(user);
        if (count == 1) {
            return true;
        }
        return false;
    }

    @Override
    public boolean containsByParams(Map<String, Object> params) {
        int count = userMapper.countUserbyParams(params);
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Override
    public User getUser(HttpServletRequest req, HttpServletResponse resp) {
        User user;
        Cookie[] cookies = req.getCookies();
        if (cookies == null) {
            return null;
        }
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("uuid")) {
                user = (User) redisTemplate.opsForValue().get(cookie.getValue());
                return user;
            }
        }
        return null;
    }

    @Override
    public void loginOut(HttpServletRequest req, HttpServletResponse resp) {
        Cookie[] cookies = req.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("uuid")) {
                    redisTemplate.delete(cookie.getValue());
                    break;
                }
            }
        }
    }


    @Override
    public boolean editUser(User user, HttpServletRequest req, HttpServletResponse resp) {
        if (userMapper.updateUser(user) > 0) {
            User newUser = userMapper.selectById(user.getId());
            Cookie[] cookies = req.getCookies();
            System.out.println("editUser:--" + cookies);
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals("uuid")) {
                        redisTemplate.opsForValue().set(cookie.getValue(), newUser, 30, TimeUnit.MINUTES);
                    }
                }
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean editPwd(Map<String, Object> params, HttpServletRequest req, HttpServletResponse resp) {
        String password = SecurityUtils.md5Hex(params.get("newPassword").toString());
        params.put("newPassword", password);
        if (userMapper.updatePwd(params) > 0) {
            loginOut(req, resp);
            return true;
        }
        return false;
    }

    @Override
    public User findByNameAndPwd(Map<String, Object> params) {
        String password = SecurityUtils.md5Hex(params.get("password").toString());
        params.put("password", password);
        return userMapper.selectByNameAndPwd(params);
    }

    @Override
    public List<User> pageByUser(Map<String, Object> params) {
        return userMapper.selectByPage(params);
    }

    @Override
    public User findById(Integer id) {
        return userMapper.selectById(id);
    }

    @Override
    public boolean editUserType(User user) {
        if (userMapper.updateUserType(user) > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean delUser(Integer id) {
        if (userMapper.deleteById(id) > 0) {
            return true;
        }
        return false;
    }


    @Override
    public User getUserByMobile(String mobile) {
        return userMapper.selectUserByMobile(mobile);
    }

    @Override
    public User getUserByEmail(String email) {
        User user = userMapper.selectUserByEmail(email);
        redisTemplate.opsForValue().set("userId", user.getId(), 5, TimeUnit.MINUTES);
        return user;
    }

    @Override
    public boolean sendEmailCode(String emailReceiver) {
        String code = CodeUtil.getCode();
        if (EmailUtil.sendEmail(code, emailReceiver, javaMailSender)) {
            redisTemplate.opsForValue().set(emailReceiver, code, 300, TimeUnit.SECONDS);
            System.out.println("发送邮件验证码成功");
            System.out.println("code: " + code);
            return true;
        }
        return false;
    }


    @Override
    public Boolean checkEmailCode(String emailReceiver, String inputCode) {
        String code = (String) redisTemplate.opsForValue().get(emailReceiver);
        System.out.println(code);
        if (StringUtils.isEmpty(code)) {
            return null;
        }
        if (inputCode.equals(code)) {
            redisTemplate.delete(emailReceiver);
            return true;
        }
        return false;
    }

    @Override
    public boolean resetPwd(User user) {
        Integer userId = (Integer) redisTemplate.opsForValue().get("userId");
        if (userId == null) {
            return false;
        }
        if (!user.getId().equals(userId)) {
            return false;
        }
        user.setPassword(SecurityUtils.md5Hex(user.getPassword()));
        int count = userMapper.updateUser(user);
        if (count == 1) {
            redisTemplate.delete("userId");
            return true;
        }
        return false;
    }

    @Override
    public boolean checkRedis(Integer id) {
        Integer userId = (Integer) redisTemplate.opsForValue().get("userId");
        return id.equals(userId);
    }

}
